#region "SqlDatabase"

/*
 * ####     Developer Name : Wang Yucai
 * 
 * ####     Development Tool : Microsoft VisualStudio 2010 Ultimate Edition
 * 
 * ####     Create Time : 2014-07-16 16:29:58
 * 
 * ####     Namespace : Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.SqlClient
 * 
 * ####     Type Name : SqlDatabase
 * 
 * ####     Full Name : Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.SqlClient.SqlDatabase
 * 
 * ####     Machine Name : GLCHQWYCWINW7
 * 
 * ####     UserName : GUOCOLAND/wangyucai
 * 
 * ####     CLR Version : 4.0.30319.18444
 * 
 * ####     Target Framework Version : 4.0
 */

#endregion

using System;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.Common;

namespace Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.SqlClient
{
    /// <summary>
    /// <para>Masterduner.SourceStudio.Practices.DevelopmentLibrary.Data.SqlClient.SqlDatabase</para>
    /// <para>
    /// 提供了访问Microsoft SQL Server操作的方法。
    /// </para>
    /// </summary>
    /// <remarks>
    /// <para>Target Framework Version : 4.0</para>
    /// <para>此类不可继承。</para>
    /// </remarks>
    public sealed class SqlDatabase : Database
    {
        private SqlConnection _sqlConnection;

        #region SqlConnection
        /// <summary>
        /// 设置或获取SQL Server数据库连接对象。
        /// </summary>
        private SqlConnection SqlConnection
        {
            get { return _sqlConnection; }
            set
            {
                _sqlConnection = value;
                base.DbConnection = value;
            }
        }
        #endregion

        #region Constructor

        /// <summary>
        /// <para>构造函数：</para>
        /// <para>初始化一个<see cref="SqlDatabase" />对象实例。</para>
        /// </summary>
        /// <param name="connectionString">SQL Server数据库连接串。</param>
        public SqlDatabase(string connectionString)
            : base(connectionString)
        {
        }

        #endregion

        #region InitializeConnection
        /// <summary>
        /// 初始化SQL Server数据库连接对象实例。
        /// </summary>
        private void InitializeConnection()
        {
            this.SqlConnection = new SqlConnection(base.ConnectionString);
        }
        #endregion

        #region InitialDbConnection
        /// <summary>
        /// 初始化SQL Server数据库连接对象实例。
        /// </summary>
        protected override void InitialDbConnection()
        {
            this.InitializeConnection();
        }
        #endregion

        #region BeginTransaction
        /// <summary>
        /// 启动一个SQL Server数据库事务。
        /// </summary>
        /// <param name="name">数据库事务名称。</param>
        /// <returns><see cref="SqlTransaction"/>对象实例。</returns>
        public SqlTransaction BeginTransaction(string name = "System.Data.SqlClient.SqlTransaction")
        {
            try
            {
                return this.SqlConnection.BeginTransaction(name);
            }
            catch (Exception ex)
            {
                throw new DatabaseExceptionWrapper(ex);
            }
        }

        /// <summary>
        /// 启动一个SQL Server数据库事务。
        /// </summary>
        /// <param name="iso"><see cref="IsolationLevel"/>中的一个值。</param>
        /// <param name="name">数据库事务名称。</param>
        /// <returns><see cref="SqlTransaction"/>对象实例。</returns>
        public SqlTransaction BeginTransaction(IsolationLevel iso, string name = "System.Data.SqlClient.SqlTransaction")
        {
            try
            {
                return this.SqlConnection.BeginTransaction(iso, name);
            }
            catch (Exception ex)
            {
                throw new DatabaseExceptionWrapper(ex);
            }
        }
        #endregion

        #region Commit
        /// <summary>
        /// 回滚一个SQL Server数据库事务。
        /// </summary>
        /// <param name="transaction"><see cref="SqlTransaction"/>对象实例。</param>
        public void Commit(SqlTransaction transaction)
        {
            base.Commit(transaction);
        }
        #endregion

        #region Rollback
        /// <summary>
        /// 回滚指定的SQL Server数据库事务对象实例。
        /// </summary>
        /// <param name="transaction"><see cref="SqlTransaction"/>对象实例。</param>
        public void Rollback(SqlTransaction transaction)
        {
            base.Rollback(transaction);
        }
        #endregion

        #region CreateCommand
        /// <summary>
        /// 创建一个SQL Server数据库命令对象实例。
        /// </summary>
        /// <param name="cmdText">数据库命令文本。</param>
        /// <param name="cmdType"><see cref="CommandType"/>中的一个值。</param>
        /// <returns><see cref="SqlCommand"/>对象实例。</returns>
        public SqlCommand CreateCommand(string cmdText, CommandType cmdType = CommandType.Text)
        {
            if (this.SqlConnection.IsNull()) this.InitializeConnection();
            SqlCommand command = new SqlCommand(cmdText, this.SqlConnection)
            {
                CommandType = cmdType,
                CommandTimeout = this.ExecuteTimeout
            };
            return command;
        }

        /// <summary>
        /// 创建一个事务性的SQL Server数据库命令对象实例。
        /// </summary>
        /// <param name="cmdText">数据库命令文本。</param>
        /// <param name="cmdType"><see cref="CommandType"/>中的一个值。</param>
        /// <param name="transaction"><see cref="SqlTransaction"/>对象实例。</param>
        /// <returns><see cref="SqlCommand"/>对象实例。</returns>
        public SqlCommand CreateCommand(string cmdText, SqlTransaction transaction, CommandType cmdType = CommandType.Text)
        {
            if (transaction.IsNull()) return this.CreateCommand(cmdText, cmdType);
            else return new SqlCommand(cmdText, transaction.Connection, transaction)
            {
                CommandType = cmdType,
                CommandTimeout = this.ExecuteTimeout
            };
        }
        #endregion

        #region CreateDbCommand
        /// <summary>
        /// 创建一个SQL Server数据库命令对象实例。
        /// </summary>
        /// <param name="cmdText">数据库命令文本。</param>
        /// <param name="cmdType"><see cref="CommandType"/>中的一个值。</param>
        /// <returns><see cref="SqlCommand"/>对象实例。</returns>
        public override DbCommand CreateDbCommand(string cmdText, CommandType cmdType = CommandType.Text)
        {
            return this.CreateCommand(cmdText, cmdType);
        }

        /// <summary>
        /// 创建一个事务性的SQL Server数据库命令对象实例。
        /// </summary>
        /// <param name="cmdText">数据库命令文本。</param>
        /// <param name="cmdType"><see cref="CommandType"/>中的一个值。</param>
        /// <param name="transaction"><see cref="SqlTransaction"/>对象实例。</param>
        /// <returns><see cref="SqlCommand"/>对象实例。</returns>
        public override DbCommand CreateDbCommand(string cmdText, DbTransaction transaction, CommandType cmdType = CommandType.Text)
        {
            return this.CreateCommand(cmdText, transaction.ForceTo<SqlTransaction>(), cmdType);
        }
        #endregion

        #region CreateParameter
        /// <summary>
        /// 创建一个SQL Server数据库命令参数对象。
        /// </summary>
        /// <param name="name">参数名称。</param>
        /// <param name="value">参数值。</param>
        /// <param name="direction"><see cref="ParameterDirection"/>中的一个值。</param>
        /// <param name="dbType"><see cref="SqlDbType"/>中的一个值。</param>
        /// <returns><see cref="SqlParameter"/>对象实例。</returns>
        public SqlParameter CreateParameter(string name, object value, ParameterDirection direction = ParameterDirection.Input, SqlDbType dbType = SqlDbType.VarChar)
        {
            return new SqlParameter(this.CreateParameterName(name), value) { Direction = direction, SqlDbType = dbType };
        }
        #endregion

        #region CreateDbParameter
        /// <summary>
        /// 创建一个SQL Server数据库命令参数对象。
        /// </summary>
        /// <param name="name">参数名称。</param>
        /// <param name="value">参数值。</param>
        /// <param name="direction"><see cref="ParameterDirection"/>中的一个值。</param>
        /// <param name="dbType"><see cref="DbType"/>中的一个值。</param>
        /// <returns><see cref="SqlParameter"/>对象实例。</returns>
        public override DbParameter CreateDbParameter(string name, object value, ParameterDirection direction = ParameterDirection.Input, DbType dbType = DbType.AnsiString)
        {
            return this.CreateParameter(name, value, direction, dbType.ToSqlDbType());
        }
        #endregion

        #region AddParameter
        /// <summary>
        /// 添加<paramref name="parameter"/>到<paramref name="cmd"/>中。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令。</param>
        /// <param name="parameter">SQL Server数据库命令参数。</param>
        public void AddParameter(SqlCommand cmd, SqlParameter parameter)
        {
            base.AddParameter(cmd, parameter);
        }
        #endregion

        #region AddParameters
        /// <summary>
        /// 添加<paramref name="parameters"/>到<paramref name="cmd"/>中。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令。</param>
        /// <param name="parameters">SQL Server数据库命令参数数组。</param>
        public void AddParameters(SqlCommand cmd, params SqlParameter[] parameters)
        {
            base.AddParameters(cmd, parameters);
        }
        #endregion

        #region InitializeCommandConnection
        /// <summary>
        /// 初始化SQL Server数据库的连接。
        /// </summary>
        /// <param name="cmd"><see cref="DbCommand"/>对象实例。</param>
        private void InitializeCommandConnection(DbCommand cmd)
        {
            if (cmd.Connection.IsNull())
            {
                if (this.SqlConnection.IsNull()) this.InitializeConnection();
                cmd.Connection = this.SqlConnection;
            }
        }
        #endregion

        #region Fill
        /// <summary>
        /// 执行SQL Server查询命令，并填充<paramref name="dataSet"/>。
        /// </summary>
        /// <param name="selectCmd">SQL Server数据库查询命令。</param>
        /// <param name="dataSet"><see cref="DataSet"/>对象实例。</param>
        /// <param name="dataSetName">结果集名称。</param>
        public override void Fill(DbCommand selectCmd, DataSet dataSet, string dataSetName = Database.DefaultDataSetName)
        {
            this.InitializeCommandConnection(selectCmd);
            using (SqlDataAdapter dataAdapter = new SqlDataAdapter(selectCmd.ForceTo<SqlCommand>()))
            {
                try
                {
                    dataAdapter.Fill(dataSet);
                    this.RaiseDatabaseEvent(new DatabaseEventArgs(true, dataSet, typeof(DataSet), null));
                }
                catch (Exception ex)
                {
                    base.ThrowAndRaise(new DatabaseExceptionWrapper(ex));
                }
                dataSet.DataSetName = dataSetName;
            }
        }

        /// <summary>
        /// 执行SQL Server查询命令，并填充<paramref name="dataSet"/>。
        /// </summary>
        /// <param name="selectCmd">SQL Server数据库查询命令。</param>
        /// <param name="dataSet"><see cref="DataSet"/>对象实例。</param>
        /// <param name="dataSetName">结果集名称。</param>
        public void Fill(SqlCommand selectCmd, DataSet dataSet, string dataSetName = Database.DefaultDataSetName)
        {
            this.Fill(selectCmd, dataSet, dataSetName);
        }
        #endregion

        #region ExecuteDataSet
        /// <summary>
        /// 执行SQL Server数据库查询并返回数据集。
        /// </summary>
        /// <param name="selectCmd">SQL Server数据库查询命令。</param>
        /// <param name="dataSetName">数据集名称。</param>
        /// <returns><see cref="DataSet"/>对象实例。</returns>
        public DataSet ExecuteDataSet(SqlCommand selectCmd, string dataSetName = Database.DefaultDataSetName)
        {
            return base.ExecuteDataSet(selectCmd, dataSetName);
        }
        #endregion

        #region ExecuteReader
        /// <summary>
        /// 执行SQL Server数据库命令并返回<see cref="SqlDataReader"/>对象实例。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令</param>
        /// <param name="behavior"><see cref="CommandBehavior"/>中的一个值。</param>
        /// <returns><see cref="SqlDataReader"/>对象实例。</returns>
        public SqlDataReader ExecuteReader(SqlCommand cmd, CommandBehavior behavior = CommandBehavior.Default)
        {
            this.InitializeCommandConnection(cmd);
            return base.ExecuteReader(cmd, behavior).ForceTo<SqlDataReader>();
        }

        /// <summary>
        /// 执行SQL Server数据库命令，并调用<see cref="DatabaseReaderHandler{T}"/>委托处理每一条数据。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令。</param>
        /// <param name="handler"><see cref="DatabaseReaderHandler{T}"/>委托。</param>
        /// <param name="behavior"><see cref="CommandBehavior"/>中的一个值。</param>
        public void ExecuteReader(SqlCommand cmd, DatabaseReaderHandler<SqlDataReader> handler, CommandBehavior behavior = CommandBehavior.Default)
        {
            base.ExecuteReader<SqlDataReader>(cmd, handler, behavior);
        }

        /// <summary>
        /// 执行SQL Server数据库命令，并调用<see cref="DatabaseReaderHandler{T}"/>委托处理每一条数据。
        /// </summary>
        /// <param name="cmdText">SQL Server数据库命令文本。</param>
        /// <param name="handler"><see cref="DatabaseReaderHandler{T}"/>委托。</param>
        /// <param name="behavior"><see cref="CommandBehavior"/>中的一个值。</param>
        public void ExecuteReader(string cmdText, DatabaseReaderHandler<SqlDataReader> handler, CommandBehavior behavior = CommandBehavior.Default)
        {
            this.ExecuteReader(this.CreateCommand(cmdText), handler, behavior);
        }
        #endregion

        #region ExecuteSqlReader
        /// <summary>
        /// 执行SQL Server数据库命令文本，并返回<see cref="SqlDataReader"/>。
        /// </summary>
        /// <param name="cmdText">SQL Server数据库命令文本。</param>
        /// <param name="behavior"><see cref="CommandBehavior"/>中的一个值。</param>
        /// <returns><see cref="SqlDataReader"/>对象实例。</returns>
        public SqlDataReader ExecuteSqlReader(string cmdText, CommandBehavior behavior = CommandBehavior.Default)
        {
            return this.ExecuteReader(this.CreateCommand(cmdText), behavior);
        }
        #endregion

        #region ExecuteNonQuery
        /// <summary>
        /// 执行SQL Server数据库命令，并返回映像行数。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令。</param>
        /// <returns>影响行数。</returns>
        public int ExecuteNonQuery(SqlCommand cmd)
        {
            return base.ExecuteNonQuery(cmd);
        }
        #endregion

        #region ExecuteScalar
        /// <summary>
        /// 执行SQL Server数据库命令，并返回标量值。
        /// </summary>
        /// <param name="cmd">SQL Server数据库命令。</param>
        /// <returns>标量值。</returns>
        public object ExecuteScalar(SqlCommand cmd)
        {
            return base.ExecuteScalar(cmd);
        }
        #endregion
    }
}

#region README

/*
 * ####     ©2014 Wang Yucai
 * 
 * ####     Contact me
 *                  
 *                  E-mail : Masterduner@Yeah.net
 *                  Mobile : 13621384677
 *                  QQ : 180261899
 */

#endregion